﻿using System;
using System.Collections.Generic;
using System.IO;
using FeedsLibrary.Feeds.Abstract;
using Ionic.Zip;

namespace FeedsLibrary.Feeds
{
    public class CompoundChannel : IChannel
    {
        private List<IChannel> _allChannels;
        public IChannel _mergedChannel;
        private string _title;
        public TagList TagList { get; set; }
        public bool TagsOnly { get; set; }
        public DateTime CurrentDay { get; set; }

        public CompoundChannel( FeedDetail feed, DateTime currentDate, string tagFilePath )
        {
            CurrentDay = currentDate;
            Title = feed.Name;
            Days = feed.Days;
            TagsOnly = feed.TagsOnly;
            _allChannels = new List<IChannel>();

            //create the channels
            foreach ( ChannelDetail t in feed.ChannelDetails )
            {
                ChannelDetail cd = t;
                _allChannels.Add( ChannelFactory.CreateFeed( cd.Url, cd.IconUrl, CurrentDay, Days, TagsOnly ) );
            }

            _mergedChannel = ChannelFactory.CreateEmptyFeed();
            _mergedChannel.Title = _title;
            _mergedChannel.Description = _title;
            _mergedChannel.LastBuildDate = DateTime.Now;

            //create a compound channel by merging two others
            foreach ( IChannel t in _allChannels )
            {
                _mergedChannel.Merge( t );
            }

            if ( File.Exists( Path.Combine( tagFilePath, feed.Name.Replace( " ", "_" ) + ".tags" ) ) )
            {
                TagList = new TagList( Path.Combine( tagFilePath, feed.Name.Replace( " ", "_" ) + ".tags" ) );

                for ( int j = 0; j < _mergedChannel.ItemCount(); j++ )
                {
                    IItem i = ( IItem )( _mergedChannel[ ( j ) ] );

                    List<string> l = TagList.ParseTags( i.Title + " " + i.Description );

                    if ( l.Count > 0 )
                    {
                        i.Tags = l;
                    }
                }
            }
        }

        public void Update()
        {
            //create a compound channel by merging two others
            foreach ( IChannel t in _allChannels )
            {
                t.Update();
            }

            _mergedChannel = ChannelFactory.CreateEmptyFeed();

            //create a compound channel by merging two others
            foreach ( IChannel t in _allChannels )
            {
                _mergedChannel.Merge( t );
            }
        }

        public void Merge(IChannel channel)
        {
        }

        public object this[ int index ]
        {
            get
            {
                return _mergedChannel[ index ];
            }
        }

        public int ItemCount()
        {
            return _mergedChannel.ItemCount();
        }

        public void Save( string fileName )
        {
            ActualSave(fileName);
        }

        private void ActualSave(string filename)
        {
            Console.WriteLine(filename);
            _mergedChannel.TagList = TagList;
            _mergedChannel.Save(filename);
            ZipItUp( filename );
        }

        private static void ZipItUp(string filename)
        {
            using (ZipFile zip = new ZipFile())
            {
                // add the file at the root of the zip
                zip.AddFile(filename,"");
                //and save as Zip64Option file
                zip.Save(filename.Replace( @"xml",@"zip" ));
            }
        }

        public MemoryStream Stream()
        {
            return _mergedChannel.Stream();
        }

        #region properties

        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                _title = value;
                FileName = _title;

                // Get a list of invalid path characters.
                char[] invalidPathChars = Path.GetInvalidPathChars();

                // Display each invalid character to the console.
                foreach ( char invalidPChar in invalidPathChars )
                {
                    FileName = FileName.Replace( invalidPChar, ' ' );
                }

                FileName = FileName.Replace( ' ', '_' );
            }
        }

        public string FileName { get; set; }

        public int Days { get; set; }

        public string Description
        {
            get
            {
                return _mergedChannel.Description;
            }
            set
            {
                _mergedChannel.Description = value;
            }
        }

        public DateTime LastBuildDate
        {
            get
            {
                return _mergedChannel.LastBuildDate;
            }
            set
            {
                _mergedChannel.LastBuildDate = value;
            }
        }

        #endregion
    }
}